﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Networking;

public class Entity : NetworkBehaviour
{
    [CompilerGenerated]
    private static Func<bool> <>f__am$cache6;
    private static int kListnetworkVariableKeys = -1763494215;
    private static int kListnetworkVariableValues;
    private Model m_model;
    private GameNetworkProximityChecker networkProximityChecker;
    [SerializeField, SyncVar]
    private SyncListString networkVariableKeys = new SyncListString();
    private SyncDict<string, string> networkVariables;
    [SyncVar, SerializeField]
    private SyncListString networkVariableValues = new SyncListString();

    static Entity()
    {
        NetworkBehaviour.RegisterSyncListDelegate(typeof(Entity), kListnetworkVariableKeys, new NetworkBehaviour.CmdDelegate(Entity.InvokeSyncListnetworkVariableKeys));
        kListnetworkVariableValues = 0x7d7788a7;
        NetworkBehaviour.RegisterSyncListDelegate(typeof(Entity), kListnetworkVariableValues, new NetworkBehaviour.CmdDelegate(Entity.InvokeSyncListnetworkVariableValues));
        NetworkCRC.RegisterBehaviour("Entity", 0);
    }

    private void AssignVariable(string name, string valueJson)
    {
        System.Type type = base.GetType();
        FieldInfo instanceField = type.GetInstanceField(name);
        if (instanceField != null)
        {
            NetworkVariableAttribute customAttribute = instanceField.GetCustomAttribute<NetworkVariableAttribute>(true);
            if (customAttribute != null)
            {
                object obj2 = NetworkUtility.DeseralizeParamater(valueJson, instanceField.FieldType);
                MethodInfo instanceMethod = type.GetInstanceMethod(customAttribute.hook);
                if (instanceMethod != null)
                {
                    object[] parameters = new object[] { obj2 };
                    instanceMethod.Invoke(this, parameters);
                }
                instanceField.SetValue(this, obj2);
            }
        }
    }

    protected virtual void Awake()
    {
        this.networkIdentity = base.GetComponent<NetworkIdentity>();
        this.networkProximityChecker = base.GetComponent<GameNetworkProximityChecker>();
        if (!GameUtility.isLevelEditorScene)
        {
            this.InitNetworkVariables();
            if (<>f__am$cache6 == null)
            {
                <>f__am$cache6 = () => IngameScene.isLoaded;
            }
            this.StartWaitUntil(<>f__am$cache6, new Action(this.OnStart));
        }
        this.networkVariableKeys.InitializeBehaviour(this, kListnetworkVariableKeys);
        this.networkVariableValues.InitializeBehaviour(this, kListnetworkVariableValues);
    }

    private void InitNetworkVariables()
    {
        this.networkVariables = new SyncDict<string, string>(this.networkVariableKeys, this.networkVariableValues);
        this.networkVariables.Callback = (name, valueJson) => this.AssignVariable(name, valueJson);
    }

    protected static void InvokeSyncListnetworkVariableKeys(NetworkBehaviour obj, NetworkReader reader)
    {
        if (!NetworkClient.active)
        {
            Debug.LogError("SyncList networkVariableKeys called on server.");
        }
        else
        {
            ((Entity) obj).networkVariableKeys.HandleMsg(reader);
        }
    }

    protected static void InvokeSyncListnetworkVariableValues(NetworkBehaviour obj, NetworkReader reader)
    {
        if (!NetworkClient.active)
        {
            Debug.LogError("SyncList networkVariableValues called on server.");
        }
        else
        {
            ((Entity) obj).networkVariableValues.HandleMsg(reader);
        }
    }

    public override void OnDeserialize(NetworkReader reader, bool initialState)
    {
        if (initialState)
        {
            SyncListString.ReadReference(reader, this.networkVariableKeys);
            SyncListString.ReadReference(reader, this.networkVariableKeys);
            SyncListString.ReadReference(reader, this.networkVariableValues);
            SyncListString.ReadReference(reader, this.networkVariableValues);
        }
        else
        {
            int num = (int) reader.ReadPackedUInt32();
            if ((num & 1) != 0)
            {
                SyncListString.ReadReference(reader, this.networkVariableKeys);
            }
            if ((num & 2) != 0)
            {
                SyncListString.ReadReference(reader, this.networkVariableKeys);
            }
            if ((num & 4) != 0)
            {
                SyncListString.ReadReference(reader, this.networkVariableValues);
            }
            if ((num & 8) != 0)
            {
                SyncListString.ReadReference(reader, this.networkVariableValues);
            }
        }
    }

    protected virtual void OnDestroy()
    {
    }

    protected virtual void OnDisable()
    {
        GameGUIHelper.UnregisterGUIAction(new Action(this.OnHUDGUI));
    }

    protected virtual void OnEnable()
    {
        if (!GameUtility.isLevelEditorScene)
        {
            GameGUIHelper.RegisterGUIAction(new Action(this.OnHUDGUI));
        }
    }

    protected virtual void OnHUDGUI()
    {
        GUI.skin = GameResources.GUISkin;
    }

    public override bool OnSerialize(NetworkWriter writer, bool forceAll)
    {
        if (forceAll)
        {
            SyncListString.WriteInstance(writer, this.networkVariableKeys);
            SyncListString.WriteInstance(writer, this.networkVariableKeys);
            SyncListString.WriteInstance(writer, this.networkVariableValues);
            SyncListString.WriteInstance(writer, this.networkVariableValues);
            return true;
        }
        bool flag = false;
        if ((base.syncVarDirtyBits & 1) != 0)
        {
            if (!flag)
            {
                writer.WritePackedUInt32(base.syncVarDirtyBits);
                flag = true;
            }
            SyncListString.WriteInstance(writer, this.networkVariableKeys);
        }
        if ((base.syncVarDirtyBits & 2) != 0)
        {
            if (!flag)
            {
                writer.WritePackedUInt32(base.syncVarDirtyBits);
                flag = true;
            }
            SyncListString.WriteInstance(writer, this.networkVariableKeys);
        }
        if ((base.syncVarDirtyBits & 4) != 0)
        {
            if (!flag)
            {
                writer.WritePackedUInt32(base.syncVarDirtyBits);
                flag = true;
            }
            SyncListString.WriteInstance(writer, this.networkVariableValues);
        }
        if ((base.syncVarDirtyBits & 8) != 0)
        {
            if (!flag)
            {
                writer.WritePackedUInt32(base.syncVarDirtyBits);
                flag = true;
            }
            SyncListString.WriteInstance(writer, this.networkVariableValues);
        }
        if (!flag)
        {
            writer.WritePackedUInt32(base.syncVarDirtyBits);
        }
        return flag;
    }

    protected virtual void OnStart()
    {
    }

    public override void OnStartClient()
    {
        base.OnStartClient();
        this.networkVariables.OnStartClient();
        foreach (KeyValuePair<string, string> pair in this.networkVariables.dict)
        {
            this.AssignVariable(pair.Key, pair.Value);
        }
    }

    public void SetLayer(GameLayers layer)
    {
        base.gameObject.layer = layer.index;
        foreach (Collider collider in base.GetComponentsInChildren<Collider>(true))
        {
            collider.gameObject.layer = base.gameObject.layer;
        }
    }

    protected void SetNetworkVariable(string name, object value)
    {
        this.networkVariables.SetValue(name, NetworkUtility.SerializeParamater(value));
    }

    private void UNetVersion()
    {
    }

    public virtual string displayName
    {
        get
        {
            return this.GetLocalizedAssetName();
        }
    }

    public bool dontHideAgainIfObserved
    {
        get
        {
            return this.networkProximityChecker.dontHideAgainIfObserved;
        }
        set
        {
            this.networkProximityChecker.dontHideAgainIfObserved = value;
        }
    }

    public Model model
    {
        get
        {
            return ((this.m_model == null) ? (this.m_model = base.GetComponent<Model>()) : this.m_model);
        }
    }

    public NetworkIdentity networkIdentity { get; private set; }

    public SyncListString NetworknetworkVariableKeys
    {
        get
        {
            return this.networkVariableKeys;
        }
        [param: In]
        set
        {
            base.SetSyncVar<SyncListString>(value, ref this.networkVariableKeys, 1);
        }
    }

    public SyncListString NetworknetworkVariableValues
    {
        get
        {
            return this.networkVariableValues;
        }
        [param: In]
        set
        {
            base.SetSyncVar<SyncListString>(value, ref this.networkVariableValues, 4);
        }
    }
}

